home *** CD-ROM | disk | FTP | other *** search
/ Introduction to 3D Game …ogramming with DirectX 12 / Introduction-to-3D-Game-Programming-with-DirectX-12.ISO / Code.Textures / Chapter 23 Character Animation / SkinnedMesh / Shaders / SsaoBlur.hlsl < prev   
Encoding:
Text File  |  2016-03-02  |  4.1 KB  |  147 lines

  1. //=============================================================================
  2. // SsaoBlur.hlsl by Frank Luna (C) 2011 All Rights Reserved.
  3. //
  4. // Performs a bilateral edge preserving blur of the ambient map.  We use 
  5. // a pixel shader instead of compute shader to avoid the switch from 
  6. // compute mode to rendering mode.  The texture cache makes up for some of the
  7. // loss of not having shared memory.  The ambient map uses 16-bit texture
  8. // format, which is small, so we should be able to fit a lot of texels
  9. // in the cache.
  10. //=============================================================================
  11.  
  12. cbuffer cbSsao : register(b0)
  13. {
  14.     float4x4 gProj;
  15.     float4x4 gInvProj;
  16.     float4x4 gProjTex;
  17.     float4   gOffsetVectors[14];
  18.  
  19.     // For SsaoBlur.hlsl
  20.     float4 gBlurWeights[3];
  21.  
  22.     float2 gInvRenderTargetSize;
  23.  
  24.     // Coordinates given in view space.
  25.     float gOcclusionRadius;
  26.     float gOcclusionFadeStart;
  27.     float gOcclusionFadeEnd;
  28.     float gSurfaceEpsilon;
  29.  
  30.     
  31. };
  32.  
  33. cbuffer cbRootConstants : register(b1)
  34. {
  35.     bool gHorizontalBlur;
  36. };
  37.  
  38. // Nonnumeric values cannot be added to a cbuffer.
  39. Texture2D gNormalMap : register(t0);
  40. Texture2D gDepthMap  : register(t1);
  41. Texture2D gInputMap  : register(t2);
  42.  
  43. SamplerState gsamPointClamp : register(s0);
  44. SamplerState gsamLinearClamp : register(s1);
  45. SamplerState gsamDepthMap : register(s2);
  46. SamplerState gsamLinearWrap : register(s3);
  47.  
  48. static const int gBlurRadius = 5;
  49.  
  50. static const float2 gTexCoords[6] =
  51. {
  52.     float2(0.0f, 1.0f),
  53.     float2(0.0f, 0.0f),
  54.     float2(1.0f, 0.0f),
  55.     float2(0.0f, 1.0f),
  56.     float2(1.0f, 0.0f),
  57.     float2(1.0f, 1.0f)
  58. };
  59.  
  60. struct VertexOut
  61. {
  62.     float4 PosH  : SV_POSITION;
  63.     float2 TexC  : TEXCOORD;
  64. };
  65.  
  66. VertexOut VS(uint vid : SV_VertexID)
  67. {
  68.     VertexOut vout;
  69.  
  70.     vout.TexC = gTexCoords[vid];
  71.  
  72.     // Quad covering screen in NDC space.
  73.     vout.PosH = float4(2.0f*vout.TexC.x - 1.0f, 1.0f - 2.0f*vout.TexC.y, 0.0f, 1.0f);
  74.  
  75.     return vout;
  76. }
  77.  
  78. float NdcDepthToViewDepth(float z_ndc)
  79. {
  80.     // z_ndc = A + B/viewZ, where gProj[2,2]=A and gProj[3,2]=B.
  81.     float viewZ = gProj[3][2] / (z_ndc - gProj[2][2]);
  82.     return viewZ;
  83. }
  84.  
  85. float4 PS(VertexOut pin) : SV_Target
  86. {
  87.     // unpack into float array.
  88.     float blurWeights[12] =
  89.     {
  90.         gBlurWeights[0].x, gBlurWeights[0].y, gBlurWeights[0].z, gBlurWeights[0].w,
  91.         gBlurWeights[1].x, gBlurWeights[1].y, gBlurWeights[1].z, gBlurWeights[1].w,
  92.         gBlurWeights[2].x, gBlurWeights[2].y, gBlurWeights[2].z, gBlurWeights[2].w,
  93.     };
  94.  
  95.     float2 texOffset;
  96.     if(gHorizontalBlur)
  97.     {
  98.         texOffset = float2(gInvRenderTargetSize.x, 0.0f);
  99.     }
  100.     else
  101.     {
  102.         texOffset = float2(0.0f, gInvRenderTargetSize.y);
  103.     }
  104.  
  105.     // The center value always contributes to the sum.
  106.     float4 color      = blurWeights[gBlurRadius] * gInputMap.SampleLevel(gsamPointClamp, pin.TexC, 0.0);
  107.     float totalWeight = blurWeights[gBlurRadius];
  108.      
  109.     float3 centerNormal = gNormalMap.SampleLevel(gsamPointClamp, pin.TexC, 0.0f).xyz;
  110.     float  centerDepth = NdcDepthToViewDepth(
  111.         gDepthMap.SampleLevel(gsamDepthMap, pin.TexC, 0.0f).r);
  112.  
  113.     for(float i = -gBlurRadius; i <=gBlurRadius; ++i)
  114.     {
  115.         // We already added in the center weight.
  116.         if( i == 0 )
  117.             continue;
  118.  
  119.         float2 tex = pin.TexC + i*texOffset;
  120.  
  121.         float3 neighborNormal = gNormalMap.SampleLevel(gsamPointClamp, tex, 0.0f).xyz;
  122.         float  neighborDepth  = NdcDepthToViewDepth(
  123.             gDepthMap.SampleLevel(gsamDepthMap, tex, 0.0f).r);
  124.  
  125.         //
  126.         // If the center value and neighbor values differ too much (either in 
  127.         // normal or depth), then we assume we are sampling across a discontinuity.
  128.         // We discard such samples from the blur.
  129.         //
  130.     
  131.         if( dot(neighborNormal, centerNormal) >= 0.8f &&
  132.             abs(neighborDepth - centerDepth) <= 0.2f )
  133.         {
  134.             float weight = blurWeights[i + gBlurRadius];
  135.  
  136.             // Add neighbor pixel to blur.
  137.             color += weight*gInputMap.SampleLevel(
  138.                 gsamPointClamp, tex, 0.0);
  139.         
  140.             totalWeight += weight;
  141.         }
  142.     }
  143.  
  144.     // Compensate for discarded samples by making total weights sum to 1.
  145.     return color / totalWeight;
  146. }
  147.